/**
 * 过滤树
 * @param tree 树
 * @param handler 处理函数
 * @returns
 */
export const filterTree = <T>(
  tree: T[],
  handler: (arg: T) => boolean,
  fieldName = 'children',
): T[] => {
  if (!(tree instanceof Array)) return [];
  const result = tree.reduce((acc: any, cur: any) => {
    const flag = handler(cur);
    if (flag) {
      if (!cur[fieldName]) {
        return acc.concat(cur);
      } else {
        const children = filterTree(cur[fieldName], handler);
        return acc.concat({
          ...cur,
          [fieldName]: children,
        });
      }
    }

    return acc;
  }, []);

  return result;
};

/**
 * 扁平化树
 * @param tree 树
 * @param childKey 子树的key
 */
export const flatTree = <T>(tree: T[], childKey: string = 'children'): T[] => {
  return (
    tree.reduce((acc: any, cur: any) => {
      if (cur[childKey]) {
        const result = flatTree(cur[childKey], childKey);
        return acc.concat([...result, cur]);
      }
      return acc.concat(cur);
    }, []) || []
  );
};

/**
 * map树
 * @param tree 树
 * @param handler 处理函数
 * @returns
 */
export const mapTree = <T>(
  tree: T[] | undefined,
  handler: (arg: T) => any,
  fieldName = 'children',
): any[] => {
  if (!(tree instanceof Array)) return [];
  const result = tree.reduce((acc, cur) => {
    const handleItem = handler(cur);
    if (!cur[fieldName]) {
      return acc.concat({
        ...handleItem,
        children: null,
      });
    } else {
      const children = mapTree(cur[fieldName], handler);
      return acc.concat({
        ...handleItem,
        [fieldName]: children,
      });
    }
  }, []);
  return result;
};

/**
 *
 * @param tree
 * @param key
 * @param value
 * @param childKey
 */
export const treeFindItem = <T>(
  tree: T[],
  handler: (v: T) => boolean,
  childKey = 'children',
): T | undefined | null => {
  if (!(tree instanceof Array)) return null;
  let result: T | undefined;

  const walker = (array: T[]) => {
    if (result) return;
    array.forEach((item) => {
      if (handler(item)) {
        result = item;
      }
      if (item[childKey]) {
        walker(item[childKey]);
      }
    });
  };
  walker(tree);

  return result;
};

/**
 * 根据key 查找父keys
 * @param array // 树
 * @param code // 当前节点的key
 * @param key // 参数2的键名
 */
export const findParentKeys = <T>(
  array: T[],
  code: any,
  key: string,
): string[] => {
  let stack: string[] = [];
  let going = true;
  let walker = (array: T[], code: any) => {
    array.forEach((item) => {
      if (!going) return;
      stack.push(item[key]);
      if (item[key] === code) {
        going = false;
      } else if (item['children']) {
        walker(item['children'], code);
      } else {
        stack.pop();
      }
    });
    if (going) stack.pop();
  };
  walker(array, code);
  return stack;
};

/**
 * 根据key 查找父节点
 * @param array // 树
 * @param code // 当前节点的key
 * @param key // 参数2的键名
 */
export const findParents = <T>(array: T[], code: any, key: string): T[] => {
  let stack: T[] = [];
  let going = true;
  let walker = (array: any[], code: any) => {
    array.forEach((item) => {
      if (!going) return;
      stack.push(item);
      if (item[key] === code) {
        going = false;
      } else if (item['children']) {
        walker(item['children'], code);
      } else {
        stack.pop();
      }
    });
    if (going) stack.pop();
  };
  walker(array, code);
  return stack;
};

/**
 * 遍历树
 * @param tree 树
 * @param handler 处理函数
 * @param childField 子节点的key名
 */
export const forEachTree = <T>(
  tree: T[],
  handler: (arg: T) => void,
  childField = 'children',
) => {
  if (!(tree instanceof Array)) return null;

  const walker = (tree: T[]) => {
    tree.forEach((item: T) => {
      handler(item);
      if (item[childField]) {
        walker(item[childField]);
      }
    });
  };
  walker(tree);
};

export const getChildKeys = (node: any) => {
  if (!Array.isArray(node.children)) return [];
  return node.children.reduce((acc: any, cur: any) => {
    if (cur.children) {
      const childKeys = getChildKeys(cur);
      return acc.concat(cur.key, childKeys);
    }
    return acc.concat(cur.key);
  }, []);
};

export const splitSearchParams = (values = {}) => {
  return Object.entries(values)
    .filter(([key, value]) => value)
    .map(([key, value]: [string, any]) => {
      const [fieldName, operate] = key.split('__') as [string, Operate];
      let obj: SearchParam = {};
      if (!operate) {
        obj = {
          field_name: fieldName,
          operator: 'like',
          value,
        };
        return obj;
      }
      if (operate === 'between') {
        obj = {
          field_name: fieldName,
          operator: operate,
          value: value[0],
          value1: value[1],
        };
      } else if (operate === 'in') {
        obj = {
          field_name: fieldName,
          operator: operate,
          value: value.join(','),
        };
      } else
        obj = {
          field_name: fieldName,
          operator: operate,
          value,
        };

      return obj;
    });
};

export const orderParams: OrderParam[] = [
  { fieldName: 'createDate', order: 'desc' },
];
export const layout = (labelCol: number) => {
  return (wrapperCol: number) => ({
    labelCol: { span: labelCol },
    wrapperCol: { span: wrapperCol },
  });
};

/** 生成formData */
export const generateFormData = (obj: Object) => {
  const formData = new FormData();
  for (const key in obj) {
    formData.append(key, obj[key]);
  }
  return formData;
};

/** 随机产生一个数作为key */
export const ProduceKey = () => {
  return Math.random().toString(36).substr(2);
};
